/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "geofence_impl_client.h"
#include <string>
#include <cerrno>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <linux/netlink.h>
#include <unistd.h>
#include <errors.h>
#include "dummy_values_bucket.h"
#include "geofence_common.h"

using namespace OHOS::NativeRdb;
namespace OHOS {
namespace Msdp {
namespace {
static const int ERR_OK = 0;
static const int ERR_NG = -1;
}

ErrCode GeofenceImplClient::InitMsdpImpl()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    if (msdpInterface_ == nullptr) {
        msdpInterface_ = std::make_unique<IgeofenceImplInterface>();
        if (msdpInterface_ == nullptr) {
            GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "get msdp module instance failed");
            return ERR_NG;
        }
    }

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode GeofenceImplClient::RegisterLocationImpl(CallbackLocationManager callback)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    callbacksLocationMgr_ = callback;

    RegisterLocationMsdp();
    msdpInterface_->Enable();

    return ERR_OK;
}

ErrCode GeofenceImplClient::RegisterCloudImpl(const GeofenceDataUtils::PoiOptions& poiOptions,\
    CallbackCloudManager callback)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    callbacksCloudMgr_ = callback;
    RegisterCloudMsdp(poiOptions);

    return ERR_OK;
}

ErrCode GeofenceImplClient::ImplLocationCallback(GeofenceDataUtils::LocationData& locationData)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    callbacksLocationMgr_(locationData);
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode GeofenceImplClient::ImplCloudCallback(GeofenceDataUtils::CloudData& fenceData)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    callbacksCloudMgr_(fenceData);
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode GeofenceImplClient::EnableMsdp()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int32_t ret = msdpInterface_->Enable();
    if (ret < 0) {
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "Enable Msdp failed");
        return ERR_NG;
    }

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode GeofenceImplClient::DisableMsdp()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int32_t ret = msdpInterface_->Disable();
    if (ret < 0) {
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "Disable Msdp failed");
        return ERR_NG;
    }

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode GeofenceImplClient::RegisterLocationMsdp()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    if (msdpInterface_ != nullptr) {
        IgeofenceImplInterface::CallbackLocationImpl callback =
            std::bind (&GeofenceImplClient::MsdpLocationCallback, this, std::placeholders::_1);
        msdpInterface_->RegisterLocationCallback(callback);
    }

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode GeofenceImplClient::UnregisterLocationMsdp(void) const
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int32_t ret = msdpInterface_->UnregisterLocationCallback();
    if (ret < 0) {
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "unregister Msdp failed");
        return ERR_NG;
    }

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode GeofenceImplClient::RegisterCloudMsdp(const GeofenceDataUtils::PoiOptions& poiOptions)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    if (msdpInterface_ != nullptr) {
        IgeofenceImplInterface::CallbackCloudImpl callback =
            std::bind (&GeofenceImplClient::MsdpCloudCallback, this, std::placeholders::_1);
        msdpInterface_->RegisterCloudCallback(poiOptions, callback);
    }

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode GeofenceImplClient::UnregisterCloudMsdp(void) const
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int32_t ret = msdpInterface_->UnregisterCloudCallback();
    if (ret < 0) {
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "unregister Msdp failed");
        return ERR_NG;
    }

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

int32_t GeofenceImplClient::MsdpLocationCallback(GeofenceDataUtils::LocationData& locationData)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    ImplLocationCallback(locationData);
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

int32_t GeofenceImplClient::MsdpCloudCallback(GeofenceDataUtils::CloudData& fenceData)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    ImplCloudCallback(fenceData);
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

GeofenceDataUtils::CloudData GeofenceImplClient::GetCloudCacheData(const GeofenceDataUtils::PoiOptions& poiOptions)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GeofenceDataUtils::CloudData cloudData;
    cloudData = msdpInterface_->GetCloudCacheDataImpl(poiOptions);
    if (std::size(cloudData.fence) == 0) {
        GEOFENCE_HILOGE(GEOFENCE_MODULE_SERVICE, "GetCloudCacheData fail.");
        return cloudData;
    }
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return cloudData;
}

void GeofenceImplClient::SetTrack(std::string timeString, int32_t screenState, std::string cell)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    msdpInterface_->SetTrackImpl(timeString, screenState, cell);
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return;
}

void GeofenceImplClient::GetGeofenceTimestamp()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
}

void GeofenceImplClient::GetLongtitude()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
}

void GeofenceImplClient::GetLatitude()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
}
}
}

